package deepclone.stringconcat;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@BenchmarkMode(Mode.AverageTime)
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class StringConcatBenchmark {
	
	@Param({"10", "50", "100","200","400","800","1600","3200","6400","12800"})
    private int length;
	
	@Benchmark
    public void testPlus() {
        String str = "";
        for (int i = 0; i < length; i++) {
            str = str + "a";
        }
    }
	
	@Benchmark
    public void testConcat() {
    	String str = "";
        for (int i = 0; i < length; i++) {
            str = str.concat("a");
        }
    }
	
	@Benchmark
    public void testJoin() {
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < length; i++) {
            list.add("a");
        }
        StringUtils.join(list, "");
    }
	
	@Benchmark
    public void testStringBuffer() {
    	StringBuffer strBuffer = new StringBuffer();
        for (int i = 0; i < length; i++) {
            strBuffer.append("a");
        }
        strBuffer.toString();
    }
	
	@Benchmark
    public void testStringBuilder() {
        StringBuilder strBuilder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            strBuilder.append("a");
        }
        strBuilder.toString();
    }
	
	public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include("StringConcatBenchmark")
                .exclude("Helloworld")
                //.mode(Mode.Throughput)
                .warmupIterations(5)
                .measurementIterations(5)
                .forks(1)
                .build();

        new Runner(opt).run();
		
    }
	
}
